package com.chen.facemanager.controller;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateTime;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.IdcardUtil;
import cn.hutool.crypto.SecureUtil;
import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.chen.facemanager.annotations.AccessLimit;
import com.chen.facemanager.bean.Sca;
import com.chen.facemanager.bean.User;
import com.chen.facemanager.redis.AccessKey;
import com.chen.facemanager.redis.RedisService;
import com.chen.facemanager.service.InfoService;
import com.chen.facemanager.service.ScaService;
import com.chen.facemanager.service.UserService;
import com.chen.facemanager.util.FileUtils;
import com.chen.facemanager.util.Result;
import com.chen.facemanager.util.SendMS;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiImplicitParam;
import io.swagger.annotations.ApiImplicitParams;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Api(value = "/user", tags = "用户中心模块")
@RestController
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @Autowired
    private InfoService infoService;

    @Autowired
    private ScaService scaService;

    @Autowired
    RedisService redisService;


    @Value("${web.upload-path}")
    private String path;


    @Value("${appkey}")
    private String appkey;

    @ApiOperation(value = "获取酒店数据", notes = "获取酒店数据")
    @RequestMapping("/hotel")
    public Map<String, Object> testHotel() {
        Map<String, Object> rs = new HashMap<>();
        rs.put("h_name", "酒店名称");
        rs.put("h_code", "12345678912");
        rs.put("h_address", "酒店地址");
        rs.put("h_monery", 10);
        return rs;
    }

    @ApiOperation(value = "注册", notes = "注册")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "用户phone", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "用户password", required = true, dataType = "String"),
            @ApiImplicitParam(name = "macid", value = "macid", required = true, dataType = "String"),
            @ApiImplicitParam(name = "androidid", value = "androidid", required = true, dataType = "String"),
            @ApiImplicitParam(name = "imei1", value = "imei1", required = true, dataType = "String"),
            @ApiImplicitParam(name = "imei2", value = "imei2", required = true, dataType = "String"),
            @ApiImplicitParam(name = "imsi1", value = "imsi1", required = true, dataType = "String"),
            @ApiImplicitParam(name = "imsi2", value = "imsi2", required = true, dataType = "String"),
            @ApiImplicitParam(name = "deviceinfo", value = "deviceinfo", required = true, dataType = "String"),
//            @ApiImplicitParam(name = "code", value = "code", required = true, dataType = "String"),
    })
    @PostMapping("/reg")
    public Result reg(String phone, String password, String macid, String androidid, String imei1, String imei2, String imsi1, String imsi2, String deviceinfo) {
//        String s = redisService.get(AccessKey.withcode, phone, String.class);
//        if (s == null || !code.equals(s)){
//            return new Result(402, "error", "手机号或验证码不正确");
//        }
        if (!this.existPhone(phone)) {
            return new Result(401, "error", "手机号已被使用！");
        }
        User user = userService.reg(phone, SecureUtil.md5(password), macid, androidid, imei1, imei2, imsi1, imsi2, deviceinfo);
        if (user != null) {
            return new Result(200, "ok", user);
        } else {
            return new Result(400, "error", null);
        }
    }

    @ApiOperation(value = "登录", notes = "登录")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "用户phone", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "用户password", required = true, dataType = "String")
    })
    @PostMapping("/login")
    public Result login(String phone, String password) {
        User user = userService.login(phone, SecureUtil.md5(password));
        if (user != null) {
            return new Result(200, "ok", user);
        } else {
            return new Result(400, "error", null);
        }
    }


    @ApiOperation(value = "获取用户信息", notes = "获取用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "path")
    })
    @GetMapping("/get/{id}")
    public Result getUserByUserId(@PathVariable String id) {
        User user = userService.getUserByUserId(Long.parseLong(id));
        if (user != null) {
            return new Result(200, "ok", user);
        } else {
            return new Result(400, "error", null);
        }
    }


    @ApiOperation(value = "保存用户信息", notes = "保存用户信息")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "Long"),
            @ApiImplicitParam(name = "name", value = "用户name", required = true, dataType = "String"),
            @ApiImplicitParam(name = "idNumber", value = "用户idNumber", required = true, dataType = "String"),
            @ApiImplicitParam(name = "address", value = "用户address", required = true, dataType = "String"),
            @ApiImplicitParam(name = "sex", value = "用户sex", required = true, dataType = "String"),
            @ApiImplicitParam(name = "photo", value = "用户photo", required = true, dataType = "String"),
    })
    @PostMapping("/save")
    public Result saveInfo(String id, String name, String idNumber, String address, String sex, String photo) {

//        String birthday = "0000-00-00";
//        String res = HttpUtil.get("http://apis.juhe.cn/idcard/index?key=" + appkey + "&cardno=" + idNumber);
//        JSONObject jsonObject = JSON.parseObject(res);
//        if (jsonObject.get("resultcode").equals("200")) {
//            String info = jsonObject.get("result").toString();
//
//            JSONObject infos = JSON.parseObject(info);
//            address = infos.getString("area");
//            sex = infos.getString("sex");
//            birthday = infos.getString("birthday");
//        }
        System.out.println("获取到保存用户id" + id);
        Map<String, String> stringStringMap = decIdCard(idNumber);
        boolean flag = userService.saveInfo(Long.parseLong(id), name, idNumber, IdcardUtil.getProvinceByIdCard(idNumber),
                stringStringMap.get("sex"), photo,
                stringStringMap.get("birthday"));
        if (flag) {
            return new Result(200, "ok", flag);
        } else {
            return new Result(400, "error", null);
        }
    }
    public static Map<String, String> decIdCard(String id_number) {
        HashMap<String, String> map = new HashMap<>();
        map.put("address", IdcardUtil.getProvinceByIdCard(id_number));
        if (IdcardUtil.getGenderByIdCard(id_number) == 0) {
            map.put("sex", "女");
        } else {
            map.put("sex", "男");
        }
        DateTime birthDate = IdcardUtil.getBirthDate(id_number);
        map.put("birthday", DateUtil.format(birthDate, DatePattern.CHINESE_DATE_PATTERN));
        return map;
    }
    @ApiOperation(value = "修改用户手机号", notes = "修改用户手机号")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "phone", value = "用户phone", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "用户原始password", required = true, dataType = "String")
    })
    @PostMapping("/updatePhone")
    public Result updatePhone(String id, String phone, String password) {

        if (!this.existPhone(phone)) {
            return new Result(401, "error", "手机号已被使用！");
        }

        boolean t = userService.samePwd(id, SecureUtil.md5(password));

        if (t) {
            boolean f = userService.updatePhone(id, phone);
            if (f) {
                return new Result(200, "ok", null);
            } else {
                return new Result(400, "error", null);
            }
        } else {
            return new Result(404, "error", "原始密码错误！");
        }
    }

    @ApiOperation(value = "修改用户密码", notes = "修改用户密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "id", value = "用户id", required = true, dataType = "String"),
            @ApiImplicitParam(name = "oldpwd", value = "用户旧password", required = true, dataType = "String"),
            @ApiImplicitParam(name = "newpwd", value = "用户新password", required = true, dataType = "String")
    })
    @PostMapping("/updatePwd")
    public Result updatePwd(String id, String oldpwd, String newpwd) {

        boolean t = userService.samePwd(id, SecureUtil.md5(oldpwd));
        if (t) {
            boolean f = userService.updatePwd(id, SecureUtil.md5(newpwd));
            if (f) {
                return new Result(200, "ok", null);
            } else {
                return new Result(400, "error", null);
            }
        } else {
            return new Result(400, "error", "原始密码不匹配！");
        }
    }

    @ApiOperation(value = "重新设置密码", notes = "重新设置密码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "用户phone", required = true, dataType = "String"),
            @ApiImplicitParam(name = "password", value = "用户password", required = true, dataType = "String")
    })
    @PostMapping("/resetPwd")
    public Result resetPwd(String phone, String password) {
        if (this.existPhone(phone)) {
            return new Result(401, "error", "您的手机还没有注册，请先注册！");
        }
        boolean f = userService.resetPwd(phone, SecureUtil.md5(password));
        if (f) {
            return new Result(200, "ok", null);
        } else {
            return new Result(400, "error", null);
        }
    }


    @ApiOperation(value = "意见反馈", notes = "意见反馈")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "file", value = "图片", required = false, dataType = "file"),
            @ApiImplicitParam(name = "q", value = "联系方式", required = true, dataType = "String"),
            @ApiImplicitParam(name = "msg", value = "内容", required = true, dataType = "String"),
            @ApiImplicitParam(name = "uid", value = "用户id", required = false, dataType = "String")
    })
    @PostMapping("fileUpload")
    public Result upload(@RequestParam("file") MultipartFile[] file, String q, String msg, String uid) {
        StringBuffer stringBuffer = new StringBuffer();

        if (file.length > 0) {
            for (int i = 0; i < file.length; i++) {
                String fileName = "CHEN_" + System.currentTimeMillis();
                String fileType = file[i].getOriginalFilename().substring(file[i].getOriginalFilename().indexOf("."));

                if (FileUtils.upload(file[i], path, fileName + fileType)) {
                    // 上传成功，给出页面提示
                    stringBuffer.append(fileName + fileType + ",");
                }
            }
        }

        System.out.println("用户id：" + uid);
        boolean f = infoService.save(uid, msg, q, stringBuffer.toString());

        if (f) {
            return new Result(200, "ok", null);
        } else {
            return new Result(400, "error", null);
        }
    }


    //    @ApiOperation(value = "获取验证码",notes = "获取验证码")
//    @ApiImplicitParams({
//            @ApiImplicitParam(name = "phone", value = "用户phone", required = true, dataType = "String")
//    })
//    @PostMapping("/getCode")
//    @AccessLimit(seconds=1,maxCount=1)
//    public Result getCode(String phone) {
//        Map<String,String> res = new HashMap<>();
//        try {
//            String code = SendMS.OK(phone);
//            if (code == null){
//                return new Result(400,"error",null);
//            } else {
//                res.put("code",code);
//                res.put("phone",phone);
//                AccessKey ak = AccessKey.withExpire;
//                redisService.set(ak,phone,1,60*5);
//                return new Result(200,"ok", res);
//            }
//        } catch (Exception e){
//            return new Result(400,"error",null);
//        }
//    }
    @ApiOperation(value = "获取验证码", notes = "获取验证码")
    @ApiImplicitParams({
            @ApiImplicitParam(name = "phone", value = "用户phone", required = true, dataType = "String")
    })
    @PostMapping("/getCode")
    @AccessLimit(seconds = 60 * 5, maxCount = 1)
    @CrossOrigin
    public Result getCode(HttpServletRequest request) {
        String phone = request.getHeader("phone");
        if (phone == null) {
            return new Result(400, "error", null);
        }
        Map<String, String> res = new HashMap<>();
        try {
            String code = SendMS.OK(phone);
            if (code == null) {
                return new Result(400, "error", null);
            } else {
                res.put("code", code);
                res.put("phone", phone);
                AccessKey ak = AccessKey.withExpire;
                redisService.set(ak, phone, 1, 60 * 5);

                // 进一步把验证码保存在redis中
                redisService.set(AccessKey.withcode, phone, code, 60 * 5);
                return new Result(200, "ok", res);
            }
        } catch (Exception e) {
            return new Result(400, "error", null);
        }
    }


    @ApiOperation(value = "扫描二维码", notes = "扫描二维码")
    @PostMapping("/scan")
    public Result scan(@RequestBody Sca sca) {
        String uid = sca.getUid();
        String h_id = sca.getHid();
        String macid = sca.getMacid();
        String phoneX = sca.getPhoneX();
        String htype = sca.getHtype();
        try {
            scaService.saveScan(uid, h_id, htype, macid, phoneX);
            return new Result(200, "ok", "");
        } catch (Exception e) {
            return new Result(400, "error", null);
        }
    }

    public boolean existPhone(String phone) {
        List<User> usersByPhone = userService.findUsersByPhone(phone);
        return usersByPhone.size() == 0 ? true : false;
    }

    public String set(String name, Integer age, List<String> value) {
        return "";
    }
}
